home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1996 #6
/
Amiga Plus CD - 1996 - No. 06.iso
/
pd
/
programmierung
/
programmers
/
loadmod.a
< prev
next >
Wrap
Text File
|
1996-06-23
|
10KB
|
448 lines
; (Octa)MED module load routines, by Teijo Kinnunen
; MED V3.00 module support added 22-Jan-1991
; upgraded for V3.20 (OctaMED V2.00) 02-Aug-1991
; and for OctaMED Pro V3.00 02-Apr-1992
; (bug fix) 31-May-1992
; OctaMED Pro V5 support (MMD2) 18-May-1993
; OctaMED Pro V6 support (cmd pages) 16-Jan-1995
; 2 bug fixes (Thanks to Peter Kunath.) 14-Feb-1995
; V7 support 20-Sep-1995
; FastMem loading 26-Nov-1995
; MMD3 recognition 04-Dec-1995
; RequiredPlayRoutine 09-Jan-1996
; Didn't reloc MMD3s correctly... 17-Jan-1996
; FastMemPlayRecommended 29-Jan-1996
; Fixed MMD0 multi-module reloc error 25-Apr-1996
; $VER: loadmod_a 7.0 (25.4.1996)
; Function: d0 = _LoadModule(a0)
; a0 = module name
; d0 = pointer to loaded module, zero if load failed
XDEF _LoadModule,_LoadModule_Fast
XDEF _UnLoadModule
XDEF _RelocModule
XDEF _RequiredPlayRoutine
XDEF _FastMemPlayRecommended
mmd_songinfo EQU 8
mmd_blockarr EQU 16
mmd_expdata EQU 32
mmd_songsleft EQU 51
msng_numblocks EQU 504
msng_pseqs EQU 508
msng_flags EQU 767
msng_flags2 EQU 768
msng_numsamples EQU 787
CODE
_LoadModule move.l d7,-(sp)
moveq #0,d7
bsr.s LoadMod
move.l (sp)+,d7
rts
_LoadModule_Fast
move.l d7,-(sp)
moveq #1,d7
bsr.s LoadMod
move.l (sp)+,d7
rts
;if D7 = 1, load to Fast Mem always
LoadMod: movem.l a2-a4/a6/d2-d6,-(sp)
suba.l a2,a2
moveq #0,d6 ;d6 = return value (zero = error)
move.l a0,a4 ;a4 = module name
movea.l 4.w,a6
lea dosname(pc),a1
moveq #0,d0
jsr -$228(a6) ;OpenLibrary()
tst.l d0
beq xlm1
move.l d0,a3 ;a3 = DOSBase
move.l d0,a6
move.l a4,d1 ;name = d1
move.l #1005,d2 ;accessmode = MODE_OLDFILE
jsr -$1e(a6) ;Open()
move.l d0,d4 ;d4 = file handle
beq xlm2
move.l d4,d1
moveq #0,d2
moveq #1,d3 ;OFFSET_END
jsr -$42(a6) ;Seek(fh,0,OFFSET_END)
tst.l d0
bmi.w xlm3 ;-1 = error
move.l d4,d1
moveq #-1,d3 ;OFFSET_BEGINNING
jsr -$42(a6) ;Seek(fh,0,OFFSET_BEGINNING)
move.l d0,d5 ;d5 = file size
bmi.w xlm3
moveq #1,d1 ;alloc mem for beginning
moveq #6*4,d0
movea.l 4.w,a6
jsr -$c6(a6) ;AllocMem
tst.l d0
beq.w xlm3
move.l d0,a2
move.l d4,d1
move.l a2,d2
moveq #6*4,d3 ;read beginning of the mod..
move.l a3,a6
jsr -$2a(a6) ;Read...
cmp.l d3,d0
bne.w xlm3 ;error
cmp.l #'MMD3',(a2) ;Soundstudio module using mixing?
beq.s id_ok
cmp.l #'MMD2',(a2) ;Pro V5 module?
beq.s id_ok
cmp.l #'MMD1',(a2) ;Pro module?
beq.s id_ok
cmp.l #'MMD0',(a2)
bne.s xlm3 ;this is not a module!!!
id_ok btst #0,20(a2) ;test mmdflags of the module
beq.s 1$
moveq #1,d7 ;Fast Mem
1$ movea.l 4.w,a6 ;free the 24-byte buffer
moveq #6*4,d0
move.l a2,a1
jsr -$d2(a6) ;FreeMem()
suba.l a2,a2
move.l d4,d1
moveq #0,d2
moveq #-1,d3 ;OFFSET_BEGINNING
move.l a3,a6
jsr -$42(a6) ;Seek(fh,0,OFFSET_BEGINNING)
tst.l d0
bmi.s xlm3 ;seek error
movea.l 4.w,a6
move.l d5,d0
moveq #1,d1 ;mem type: PUBLIC
tst.b d7 ;force Fast Mem
bne.s 2$
moveq #3,d1 ;mem type: PUBLIC|CHIP
2$ jsr -$c6(a6) ;AllocMem()
tst.l d0
beq.s xlm3
move.l d0,a4 ;a4 = pointer to module
move.l d4,d1 ;file
move.l d0,d2 ;buffer
move.l d5,d3 ;length
move.l a3,a6
jsr -$2a(a6) ;Read()
cmp.l d5,d0
bne.s xlm4 ;something wrong...
movea.l a4,a0
bsr.w _RelocModule
move.l a4,d6 ;no error...
bra.s xlm3
xlm4 move.l a2,a1 ;error: free the memory
move.l d5,d0
movea.l 4.w,a6
jsr -$d2(a6) ;FreeMem()
xlm3 move.l a2,d0 ;24-byte buffer exists?
beq.s 1$
movea.l 4.w,a6
moveq #6*4,d0
move.l a2,a1
jsr -$d2(a6) ;FreeMem()
1$ move.l a3,a6 ;close the file
move.l d4,d1
jsr -$24(a6) ;Close(fhandle)
xlm2 move.l a3,a1 ;close dos.library
movea.l 4,a6
jsr -$19e(a6)
xlm1 move.l d6,d0 ;push return value
movem.l (sp)+,a2-a4/a6/d2-d6 ;restore registers
rts ;and exit...
dosname dc.b 'dos.library',0
; Function: _RelocModule(a0)
; a0 = pointer to module
; This function is a bit strangely arranged around the small reloc-routine.
reloci move.l 24(a2),d0
beq.s xloci
movea.l d0,a0
moveq #0,d0
move.b msng_numsamples(a1),d0 ;number of samples
subq.b #1,d0
relocs bsr.s relocentr
move.l -4(a0),d3 ;sample ptr
beq.s nosyn
move.l d3,a3
tst.w 4(a3)
bpl.s nosyn ;type >= 0
move.w 20(a3),d2 ;number of waveforms
lea 278(a3),a3 ;ptr to wf ptrs
subq.w #1,d2
relsyn add.l d3,(a3)+
dbf d2,relsyn
nosyn dbf d0,relocs
xloci rts
norel addq.l #4,a0
rts
relocentr tst.l (a0)
beq.s norel
add.l d1,(a0)+
rts
_RelocModule:
movem.l a2-a4/d2-d4,-(sp)
movea.l a0,a2
move.l a2,d1 ;d1 = ptr to start of module
bsr.s relocp
movea.l mmd_songinfo(a2),a1
bsr.s reloci
move.b mmd_songsleft(a2),d4
rel_lp bsr.s relocb
cmp.b #'T',3(a2)
beq.s norelmmd2
cmp.b #'2',3(a2) ;MMD2?
bcs.s norelmmd2
bsr.w relocmmd2sng
norelmmd2 move.l mmd_expdata(a2),d0 ;extension struct
beq.s rel_ex
move.l d0,a0
bsr.s relocentr ;ptr to next module
bsr.s relocentr ;InstrExt...
addq.l #4,a0 ;skip sizes of InstrExt
; We reloc the pointers of MMD0exp, so anybody who needs them can easily
; read them.
bsr.s relocentr ;annotxt
addq.l #4,a0 ;annolen
bsr.s relocentr ;InstrInfo
addq.l #8,a0
bsr.s relocentr ;rgbtable (not useful for most people)
addq.l #4,a0 ;skip channelsplit
bsr.s relocentr ;NotationInfo
bsr.s relocentr ;songname
addq.l #4,a0 ;skip song name length
bsr.s relocentr ;MIDI dumps
bsr.s relocmdd
bsr.s relocentr ;mmdinfo
bsr.s relocentr ;mmdrexx
bsr.w relocrx
bsr.s relocentr ;mmdcmd3x
bsr.w reloccmd3x
subq.b #1,d4 ;songs left..?
bcs.s rel_ex
move.l d0,a0
move.l (a0),d0
beq.s rel_ex
move.l d0,a2
bsr.s relocp
movea.l 8(a2),a1
bra.s rel_lp
rel_ex movem.l (sp)+,d2-d4/a2-a4
rts
relocp lea mmd_songinfo(a2),a0
bsr.w relocentr
addq.l #4,a0
bsr.w relocentr
addq.l #4,a0
bsr.w relocentr
addq.l #4,a0
bra.w relocentr
relocb move.l mmd_blockarr(a2),d0
beq.s xlocb
movea.l d0,a0
move.w msng_numblocks(a1),d0
subq.b #1,d0
rebl bsr relocentr
dbf d0,rebl
cmp.b #'T',3(a2) ;MMD0 (= MCNT)
beq.s xlocb
cmp.b #'1',3(a2) ;test MMD type
bge.w relocbi
xlocb rts
relocmdd movem.l d0/a0,-(sp)
tst.l -(a0)
beq.s xlocmdd
movea.l (a0),a0
move.w (a0),d0 ;# of msg dumps
addq.l #8,a0
1$ beq.s xlocmdd
bsr relocentr
bsr.s relocdmp
subq.w #1,d0
bra.s 1$
xlocmdd movem.l (sp)+,d0/a0
rts
relocrxtrig movem.l d0/a0,-(sp)
subq.l #4,a0
2$ move.l (a0),d0
beq.s 1$
move.l d0,a0
addq.l #8,a0
bsr relocentr ;command name
bsr relocentr ;port name
move.l d0,a0
bra.s 2$
1$ movem.l (sp)+,d0/a0
rts
relocrx movem.l d0/a0,-(sp)
move.l -(a0),d0
beq.s 1$
move.l d0,a0
addq.l #4,a0 ;skip res, trigcmdlen
bsr relocentr
bsr.s relocrxtrig
1$ movem.l (sp)+,d0/a0
rts
reloccmd3x movem.l d0/a0,-(sp)
move.l -(a0),d0
beq.s 1$
move.l d0,a0
addq.l #4,a0 ;skip struct_vers, pad, num_of_settings
bsr relocentr ;ctrlr_types
bsr relocentr ;ctrlr_numbers
1$ movem.l (sp)+,d0/a0
rts
relocdmp move.l -4(a0),d3
beq.s xlocdmp
exg.l a0,d3 ;save
addq.l #4,a0
bsr relocentr ;reloc data pointer
move.l d3,a0 ;restore
xlocdmp rts
relocbi move.w msng_numblocks(a1),d0
move.l a0,a3
biloop subq.w #1,d0
bmi.s xlocdmp
move.l -(a3),a0
addq.l #4,a0
bsr relocentr ;BlockInfo ptr
tst.l -(a0)
beq.s biloop
move.l (a0),a0
bsr relocentr ;hldata
bsr relocentr ;block name
addq.l #4,a0 ;skip blocknamelen
bsr relocentr ;pagetable
tst.l -(a0)
bne.s relocpgtbl
bra.s biloop
; take care of the new features of MMD2s
relocmmd2sng move.l mmd_songinfo(a2),a0
lea msng_pseqs(a0),a0
bsr relocentr ;playseqtable
bsr relocentr ;sectiontable
bsr relocentr ;trackvols
addq.l #4,a0
bsr relocentr ;trackpans
move.w -6(a0),d0 ;numpseqs
move.l -20(a0),a0 ;get back to playseqtable
subq.w #1,d0
psqtblloop bsr relocentr
dbf d0,psqtblloop
rts
relocpgtbl movea.l (a0),a4 ;page table list hdr
move.w (a4),d2
subq.w #1,d2
lea 4(a4),a0
pgtblloop bsr relocentr
dbf d2,pgtblloop
bra biloop
; Function: _UnLoadModule(a0)
; a0 = pointer to module
_UnLoadModule:
move.l a6,-(sp)
move.l a0,d0
beq.s xunl
movea.l 4,a6
move.l 4(a0),d0
beq.s xunl
movea.l a0,a1
jsr -$d2(a6) ;FreeMem()
xunl move.l (sp)+,a6
rts
; Function: _RequiredPlayRoutine(a0)
; a0 = pointer to module
; Returns:
; 0 = 4 channel routine (or no module)
; 1 = 5-8 channel routine
; 2 = mixing routine
_RequiredPlayRoutine:
move.l a0,d0
beq.s 3$
move.l 8(a0),a0 ;song struct
tst.b msng_flags2(a0) ;mixing?
bmi.s 2$
btst #6,msng_flags(a0) ;5-8 channel?
bne.s 1$
3$ moveq #0,d0
rts
1$ moveq #1,d0
rts
2$ moveq #2,d0
rts
; Function: _FastMemPlayRecommended(a0)
; a0 = pointer to module
; Returns:
; 0 = plays perfectly without FastMemPlay
; 1 = may not play perfectly without FastMemPlay
_FastMemPlayRecommended:
movem.l d2/a2,-(sp)
move.l a0,d1
beq.s fmpr_ret0
movea.l mmd_songinfo(a0),a1
moveq #0,d1
move.b msng_numsamples(a1),d1
move.l 24(a0),d0 ;sample array
beq.s fmpr_nosamples
movea.l d0,a1
move.l d1,d0
subq.l #1,d0
1$ move.l (a1)+,d2
beq.s 2$
movea.l d2,a2 ;instrument address
move.l (a2),d2 ;length
swap d2 ;upper word...
lsr.w #1,d2
bne.s fmpr_ret1 ;length >= 131072
2$ dbra d0,1$
fmpr_nosamples move.l mmd_expdata(a0),d0
beq.s fmpr_ret0
movea.l d0,a1
move.l 4(a1),d0 ;exp_smp
beq.s fmpr_ret0
move.w 8(a1),d1
beq.s fmpr_ret0
move.w 10(a1),d2
cmp.w #18,d2
blt.s fmpr_ret0 ;no long repeat
movea.l d0,a1
subq.w #1,d1
1$ move.l 10(a1),d0
or.l 14(a1),d0
lsr.l #1,d0
bcs.s fmpr_ret1 ;odd... return 1
swap d0
tst.w d0
bne.s fmpr_ret1 ;start/len >= 131072
adda.w d2,a1
dbra d1,1$
fmpr_ret0 moveq #0,d0
fmpr_ret movem.l (sp)+,d2/a2
rts
fmpr_ret1 moveq #1,d0
bra.s fmpr_ret
END